package com.thunder.kocho.circle;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;

import com.thunder.kocho.R;

/**
 * 圆形头像控件的基本类
 * @author Hilex
 * @date 2021-3-7
 */
public abstract class BaseCircleView extends View {

    private Paint mCirclePaint;
    protected Rect mCircleRect;
    private BitmapShader mBitmapShader;
    private int mBitmapWidth;

    //图片中心点
    private float bcx;
    private float bcy;

    protected Rect mOuterRingRect;

    private int mCircleRes;

    private final static int DEFAULT_HEIGHT=100;
    private final static int DEFAULT_WIDTH=100;

    public BaseCircleView(Context context){
        this(context,null);
    }

    public BaseCircleView(Context context,AttributeSet attrs){
        this(context,attrs,0);
    }

    public BaseCircleView(Context context, AttributeSet attrs,int defStyle){
        super(context,attrs,defStyle);
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.BaseCircleView,defStyle,0);
        mCircleRes=typedArray.getResourceId(R.styleable.BaseCircleView_circleRes,R.drawable.aobing);
        typedArray.recycle();
        initSubAttr(context,attrs,defStyle);
        init();
    }

    protected abstract void initSubAttr(Context context,AttributeSet attrs,int defStyle);

    protected void init(){
        mCirclePaint=new Paint();
        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),mCircleRes);
        mBitmapWidth=bitmap.getWidth();
        bcx=bitmap.getWidth()/2f;
        bcy=bitmap.getHeight()/2f;
        mBitmapShader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Rect rect=clipRect(w,h);
        mCircleRect= obtainCircleRect(rect);
        mOuterRingRect=obtainOuterRingRect(mCircleRect);
        float scale=(float)(rect.width())/(float)mBitmapWidth;
        Matrix matrix=new Matrix();
        //matrix.preTranslate(mCircleRect.centerX()-rect.centerX(),-mCircleRect.centerY()-rect.centerY());
        matrix.postTranslate(rect.centerX()-mCircleRect.centerX(),rect.centerY()-mCircleRect.centerY());
        matrix.setScale(scale,scale);
        mBitmapShader.setLocalMatrix(matrix);
        mCirclePaint.setShader(mBitmapShader);
    }

    /**
     * 确定最后的Circle的Rect
     * @param rect 已剪裁成正方形的整个图形的Rect
     * @return Circle的rect
     */
    protected abstract Rect obtainCircleRect(Rect rect);

    /**
     * 基于CircleRect确定最后外围装饰的Rect
     * @param rect CircleRect
     * @return 外围的Rect
     */
    protected abstract Rect obtainOuterRingRect(Rect rect);

    /**
     * 画外围的装饰
     */
    protected abstract void drawOuterRing(Canvas canvas);

    /**
     * 保持中心不变，剪成正方形Rect
     * @param w right
     * @param h bottom
     * @return 正方形的Rect
     */
    private Rect clipRect(int w,int h){
        int cx=w/2;
        int cy=h/2;
        int side=(Math.min(w,h))/2;
        return new Rect(cx-side,cy-side,cx+side,cy+side);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mCircleRect!=null){
            canvas.drawCircle(mCircleRect.centerX(),mCircleRect.centerY(),mCircleRect.width()/2f,mCirclePaint);
        }
        if(mOuterRingRect!=null){
            drawOuterRing(canvas);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height=DEFAULT_HEIGHT;
        int width=DEFAULT_WIDTH;

        int HEIGHT_MODE=MeasureSpec.getMode(heightMeasureSpec);
        int HEIGHT_SIZE=MeasureSpec.getSize(heightMeasureSpec);
        int WIDTH_MODE=MeasureSpec.getMode(widthMeasureSpec);
        int WIDTH_SIZE=MeasureSpec.getSize(widthMeasureSpec);

        if(HEIGHT_MODE==MeasureSpec.EXACTLY){
            height=HEIGHT_SIZE;
        }else if(HEIGHT_MODE==MeasureSpec.AT_MOST){
            height=Math.min(HEIGHT_SIZE,height);
        }
        if(WIDTH_MODE==MeasureSpec.EXACTLY){
            width=WIDTH_SIZE;
        }else if(WIDTH_MODE==MeasureSpec.AT_MOST){
            width=Math.min(width,WIDTH_SIZE);
        }
        setMeasuredDimension(width,height);
    }

    public void setCircleRes(int res){
        mCircleRes=res;
    }

}
